<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Debugging Tools
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora096.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora098.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Debugging Tools</H2>
<A NAME="@concepts206"></A>
<A NAME="@concepts207"></A>
There are two debugging tools. The first is a
trace mechanism that can be used on the global functions in
the toplevel loop. The second tool is a debugger that is not
used in the normal toplevel loop. After a first program run it is
possible to go back to breakpoints, and to inspect values or to restart
certain functions with different arguments. This second tool only runs
under Unix, because it duplicates the running process via a
<TT>fork</TT> (see page <A HREF="book-ora167.html#sec-fork">??</A>).<BR>
<BR>
<A NAME="toc123"></A>
<H3> Trace</H3>
<A NAME="@concepts208"></A>
<A NAME="@fonctions343"></A>
<A NAME="@fonctions344"></A>
<A NAME="@fonctions345"></A>
The trace of a function is the list of the values of its
parameters together with its result in the course of a program run.<BR>
<BR>
The trace commands are directives in the toplevel loop. They allow to
trace a function, stop its trace or to stop all active traces. These
three directives are shown in the table below.
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><B>#</B><B>trace</B> <TT>name</TT></TD>
<TD  ALIGN=left NOWRAP>trace function <TT>name</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>#</B><B>untrace</B> <TT>name</TT></TD>
<TD  ALIGN=left NOWRAP>stop tracing function <TT>name</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>#</B><B>untrace_all</B></TD>
<TD  ALIGN=left NOWRAP>stop all traces</TD>
</TR></TABLE>
</DIV><BR>
Here is a first example of the definition of a function <TT>f</TT>:


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE>;;<BR><CODE>val f : int -&gt; int = &lt;fun&gt;</CODE><BR># f<CODE> </CODE><CODE>4</CODE>;;<BR><CODE>- : int = 5</CODE><BR>

</PRE>
<BR>
<BR>
Now we will trace this function, so that its arguments and its return
value will be shown.


<PRE><BR># <CODE> </CODE>#trace<CODE> </CODE>f;;<BR><CODE>f is now traced.</CODE><BR># f<CODE> </CODE><CODE>4</CODE>;;<BR><CODE>f &lt;-- 4</CODE><BR><CODE>f --&gt; 5</CODE><BR><CODE>- : int = 5</CODE><BR>

</PRE>

Passing of the argument <EM>4</EM> to <TT>f</TT> is shown, then the
function <TT>f</TT> calculates the desired value and the result is
returned and also shown. The arguments of a function call are
indicated by a left arrow and the return value by an arrow to the
right.<BR>
<BR>

<H4> Functions of Several Arguments</H4>
Functions of several arguments (or functions returning a closure) are
also traceable. Each argument passed is shown. To distinguish the
different closures, the number of arguments already passed to the
closures is marked with a <TT>*</TT>. Let the function
<TT>verif_div</TT> take 4 numbers (a, b, q, r) corresponding to the
integer division: <I>a</I> = <I>bq</I> + <I>r</I>.


<PRE><BR># <B>let</B><CODE> </CODE>verif_div<CODE> </CODE>a<CODE> </CODE>b<CODE> </CODE>q<CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>b<CODE>*</CODE>q<CODE> </CODE><CODE>+</CODE><CODE> </CODE>r;;<BR><CODE>val verif_div : int -&gt; int -&gt; int -&gt; int -&gt; bool = &lt;fun&gt;</CODE><BR># verif_div<CODE> </CODE><CODE>1</CODE><CODE>1</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>1</CODE>;;<BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
Its trace shows the passing of 4 arguments:


<PRE><BR># <CODE> </CODE>#trace<CODE> </CODE>verif_div;;<BR><CODE>verif_div is now traced.</CODE><BR># verif_div<CODE> </CODE><CODE>1</CODE><CODE>1</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>1</CODE>;;<BR><CODE>verif_div &lt;-- 11</CODE><BR><CODE>verif_div --&gt; &lt;fun&gt;</CODE><BR><CODE>verif_div* &lt;-- 5</CODE><BR><CODE>verif_div* --&gt; &lt;fun&gt;</CODE><BR><CODE>verif_div** &lt;-- 2</CODE><BR><CODE>verif_div** --&gt; &lt;fun&gt;</CODE><BR><CODE>verif_div*** &lt;-- 1</CODE><BR><CODE>verif_div*** --&gt; true</CODE><BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Recursive Functions</H4>
<A NAME="@concepts209"></A>
The trace gives valuable information about recursive functions,
e.g. poor stopping criteria are easily detected.<BR>
<BR>
Let the function <TT>belongs_to</TT> which tests whether an integer
belongs to a list of integers be defined in the following manner:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>belongs_to<CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<TT>)</TT><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t<TT>)</TT><CODE> </CODE><CODE>||</CODE><CODE> </CODE>belongs_to<CODE> </CODE>e<CODE> </CODE>q<CODE> </CODE>;;<BR><CODE>val belongs_to : int -&gt; int list -&gt; bool = &lt;fun&gt;</CODE><BR># belongs_to<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>[</CODE><CODE>3</CODE>;<CODE>5</CODE>;<CODE>7</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : bool = false</CODE><BR># belongs_to<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>4</CODE>;<CODE> </CODE><CODE>5</CODE>;<CODE> </CODE><CODE>6</CODE>;<CODE> </CODE><CODE>7</CODE>;<CODE> </CODE><CODE>8</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
The trace of the function invocation <EM>belongs_to 4 [3;5;7]</EM>
will show the four calls of this function and the results returned.


<PRE><BR># <CODE> </CODE>#trace<CODE> </CODE>belongs_to<CODE> </CODE>;;<BR><CODE>belongs_to is now traced.</CODE><BR># belongs_to<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>[</CODE><CODE>3</CODE>;<CODE>5</CODE>;<CODE>7</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [3; 5; 7]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [5; 7]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [7]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- []</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>- : bool = false</CODE><BR>

</PRE>
<BR>
<BR>
At each call of the function <TT>belongs_to</TT> the argument
<EM>4</EM> and the list to search in are passed as arguments. When the
list becomes empty, the functions return <TT>false</TT> as a return
value which is passed along to each waiting recursive invocation.<BR>
<BR>
The following example shows the section of the list when the element
searched for appears:


<PRE><BR># belongs_to<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>4</CODE>;<CODE> </CODE><CODE>5</CODE>;<CODE> </CODE><CODE>6</CODE>;<CODE> </CODE><CODE>7</CODE>;<CODE> </CODE><CODE>8</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [1; 2; 3; 4; 5; 6; 7; 8]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [2; 3; 4; 5; 6; 7; 8]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [3; 4; 5; 6; 7; 8]</CODE><BR><CODE>belongs_to &lt;-- 4</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [4; 5; 6; 7; 8]</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>- : bool = true</CODE><BR>

</PRE>

As soon as <CODE>4</CODE> becomes head of the list, the functions
return <TT>true</TT> which gets passed along to each waiting
recursive invocation.<BR>
<BR>
If the sequence of statements around <TT>||</TT> were changed, the
function <TT>belongs_to</TT> would still return the right result but
would always have to go over the complete list.


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>belongs_to<CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE><CODE> </CODE>belongs_to<CODE> </CODE>e<CODE> </CODE>q<CODE> </CODE><CODE>||</CODE><CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t<TT>)</TT><CODE> </CODE>;;<BR><CODE>val belongs_to : int -&gt; int list -&gt; bool = &lt;fun&gt;</CODE><BR># #trace<CODE> </CODE>belongs_to<CODE> </CODE>;;<BR><CODE>belongs_to is now traced.</CODE><BR># belongs_to<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>[</CODE><CODE>3</CODE>;<CODE>5</CODE>;<CODE>7</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>belongs_to &lt;-- 3</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [3; 5; 7]</CODE><BR><CODE>belongs_to &lt;-- 3</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [5; 7]</CODE><BR><CODE>belongs_to &lt;-- 3</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [7]</CODE><BR><CODE>belongs_to &lt;-- 3</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- []</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; false</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>- : bool = true</CODE><BR>

</PRE>

Even though <CODE>3</CODE> is the first element of the list, it is
traversed completely. So, trace also provides a mechanism for the
efficiency analysis of recursive functions.<BR>
<BR>

<H4> Polymorphic Functions</H4>
<A NAME="@concepts210"></A>
The trace does not show the value corresponding to an argument of a
parameterized type. If for example the function <TT>belongs_to</TT> can be
written without an explicit type constraint:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>belongs_to<CODE> </CODE>e<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t<TT>)</TT><CODE> </CODE><CODE>||</CODE><CODE> </CODE>belongs_to<CODE> </CODE>e<CODE> </CODE>q<CODE> </CODE>;;<BR><CODE>val belongs_to : 'a -&gt; 'a list -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

The type of the function <TT>belongs_to</TT> is now polymorphic, and the
trace does no longer show the value of its arguments but replaces them
with the indication (<TT>poly</TT>).


<PRE><BR># <CODE> </CODE>#trace<CODE> </CODE>belongs_to<CODE> </CODE>;;<BR><CODE>belongs_to is now traced.</CODE><BR># belongs_to<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>[</CODE><CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>belongs_to &lt;-- &lt;poly&gt;</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [&lt;poly&gt;; &lt;poly&gt;; &lt;poly&gt;]</CODE><BR><CODE>belongs_to &lt;-- &lt;poly&gt;</CODE><BR><CODE>belongs_to --&gt; &lt;fun&gt;</CODE><BR><CODE>belongs_to* &lt;-- [&lt;poly&gt;; &lt;poly&gt;]</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>belongs_to* --&gt; true</CODE><BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
The Objective CAML toplevel loop can only show monomorphic types. Moreover,
it only keeps the inferred types of global declarations. Therefore,
after compilation of the expression <EM>belongs_to 3 [2;3;4]</EM>, the
toplevel loop in fact no longer possesses any further type information about
the function <TT>belongs_to</TT> apart form the type 
<I>'a -&gt; 'a list -&gt; bool</I>. The (monomorphic) types of <EM>3</EM>
and <EM>[2;3;4]</EM> are lost, because the values do not keep any type
information: this is static typing. This is the reason why the trace
mechanism attributes the polymorphic types <I>'a</I> and 
<I>'a list</I> to the arguments of the function <TT>belongs_to</TT>
and does not show their values.<BR>
<BR>
It is this absence of typing information in values that entails the
impossibility of constructing a generic <TT>print</TT> function of
type <I>'a -&gt; unit</I>.<BR>
<BR>

<H4> Local Functions</H4>
Local functions cannot be traced for the same reasons as above, relating again
to static typing. Only global type declarations are kept in the
environment of the toplevel loop. Still the following programming
style is common:


<PRE><BR># <B>let</B><CODE> </CODE>belongs_to<CODE> </CODE>e<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>bel_aux<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>t::q<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>e<CODE> </CODE><CODE>=</CODE><CODE> </CODE>t<TT>)</TT><CODE> </CODE><CODE>||</CODE><CODE> </CODE><TT>(</TT>bel_aux<CODE> </CODE>q<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>bel_aux<CODE> </CODE>l;;<BR><CODE>val belongs_to : 'a -&gt; 'a list -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

The global function only calls on the local function, which does the
interesting part of the work.<BR>
<BR>

<H4> Notes on Tracing</H4>
Tracing is actually the only multi-platform debugging tool. Its two
weaknesses are the absence of tracing information for local functions
and the inability to show the value of polymorphic parameters. This
strongly restricts its usage, mainly during the first steps with the language.<BR>
<BR>
<A NAME="toc124"></A>
<H3> Debug</H3>
<A NAME="@concepts211"></A>
<A NAME="@fonctions346"></A>
<TT>ocamldebug</TT>, is a debugger in the usual sense of the
word. It permits step-by-step execution, the insertion of breakpoints
and the inspection and modification of values in the environment.<BR>
<BR>
Single-stepping a program presupposes the knowledge of what comprises
a program step. In imperative programming this is an easy
enough notion: a step corresponds (more or less) to a single
instruction of the language. But this definition does not make much
sense in functional programming; one instead speaks of program
events. These are applications, entries to functions, pattern
matching, a conditional, a loop, an element of a sequence, etc.<BR>
<BR>


<H3> Warning </H3> <HR>


 This tool only runs under Unix.



<HR>

<BR>
<BR>

<H4> Compiling with Debugging Mode</H4>
<A NAME="@concepts212"></A>
The <TT>-g</TT> compiler option produces a <TT>.cmo</TT> file that allows
the generation of the necessary instructions for debugging. Only the
bytecode compiler knows about this option. It is necessary to set this
option during compilation of the files encompassing an
application. Once the executable is produced, execution in debug
mode can be accomplished with the following <TT>ocamldebug</TT> command:<BR>
<BR>
<TT>ocamldebug [</TT><TT><EM>options</EM></TT><TT>] executable [</TT><TT><EM>arguments</EM></TT><TT>]</TT><BR>
<BR>
Take the following example file <TT>fact.ml</TT> which calculates the
factorial function:


<PRE><BR><B>let</B><CODE> </CODE>fact<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>fact_aux<CODE> </CODE>p<CODE> </CODE>q<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE>p<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>fact_aux<CODE> </CODE><TT>(</TT>p<CODE>+</CODE>q<TT>)</TT><CODE> </CODE>p<CODE> </CODE><TT>(</TT>n<CODE>-</CODE><CODE>1</CODE><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><B>in</B><BR>fact_aux<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>n;;<BR>

</PRE>
<BR>
<BR>
The main program in the file <TT>main.ml</TT> goes off on a long
recursion after the call of <TT>Fact.fact</TT> on -1.


<PRE><BR><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>4</CODE>;;<BR><B>let</B><CODE> </CODE>go<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>x<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE> </CODE><CODE>-</CODE><CODE>1</CODE>;<BR><CODE> </CODE><CODE> </CODE>Fact.fact<CODE> </CODE><CODE>!</CODE>x;;<BR>go();;<BR>

</PRE>
<BR>
<BR>
The two files are compiled with the <TT>-g</TT> option:
<PRE>
$ ocamlc -g -i -o fact.exe fact.ml main.ml
val fact : int -&gt; int
val x : int ref
val go : unit -&gt; int
</PRE>
<H4> Starting the Debugger</H4>
Once an executable is compiled with debug mode, it can be run in
this mode.
<PRE>
$ ocamldebug fact.exe
        Objective Caml Debugger version 3.00

(ocd) 
</PRE><A NAME="toc125"></A>
<H3> Execution Control</H3>
Execution control is done via program events. It is possible to go
forward and backwards by <I>n</I> program events, or to go forward or
backwards to the next breakpoint (or the nth breakpoint). A breakpoint
can be set on a function or a program event. The choice of language
element is shown by line and column number or the number of
characters. This locality may be relative to a module.<BR>
<BR>
In the example below, a breakpoint is set at the fourth line of module
<TT>Main</TT>:<BR>
<BR>
<PRE>
(ocd) step 0
Loading program... done.
Time : 0
Beginning of program.
(ocd)  break @ Main 4
Breakpoint 1 at 5028 : file Main, line 4 column 3
</PRE>The initialisations of the module are done before the actual
program. This is the reason the breakpoint at line 4 occurs only after
5028 instructions.<BR>
<BR>
We go forward or backwards in the execution either by program elements
or by breakpoints. <TT>run</TT> and <TT>reverse</TT> run the program just
to the next breakpoint. The first in the direction of program
execution, the second in the backwards direction. The <TT>step</TT>
command advanced by 1 or <I>n</I> program elements, entering into
functions, <TT>next</TT> steps over them. <TT>backstep</TT> and <TT>previous</TT> respectively do the same in the backwards direction. <TT>finish</TT> finally completes the current functions invocations, whereas
<TT>start</TT> returns to the program element before the function invocation.<BR>
<BR>
To continue our example, we go forward to the breakpoint and then
execute three program instructions:

<PRE>
(ocd) run
Time : 6 - pc : 4964 - module Main
Breakpoint : 1
4   &lt;|b|&gt;Fact.fact !x;;
(ocd) step
Time : 7 - pc : 4860 - module Fact
2   &lt;|b|&gt;let rec fact_aux p q n = 
(ocd) step
Time : 8 - pc : 4876 - module Fact
6 &lt;|b|&gt;fact_aux 1 1 n;;
(ocd) step
Time : 9 - pc : 4788 - module Fact
3     &lt;|b|&gt;if n = 0 then p
</PRE>
<H4> Inspection of Values</H4>
<A NAME="@concepts213"></A>
At a breakpoint, the values of variables in the activation record can
be inspected. The <TT>print</TT> and <TT>display</TT> commands output the
values associated with a variable according to the different depths.<BR>
<BR>
We will print the value of <TT>n</TT>, then go back three steps to
print the contents of <TT>x</TT>:

<PRE>
(ocd) print n
n : int = -1
(ocd) backstep 3    
Time : 6 - pc : 4964 - module Main
Breakpoint : 1
4   &lt;|b|&gt;Fact.fact !x;;
(ocd) print x
x : int ref = {contents=-1}
</PRE>
Access to the fields of a record or via the index of an array is
accepted by the printing commands.

<PRE>
(ocd) print x.contents
1 : int = -1
</PRE>
<H4> Execution Stack</H4>
<A NAME="@concepts214"></A>
The execution stack permits a visualization of the entanglement of
function invocations. The <TT>backtrace</TT> or <TT>bt</TT> command shows
the stack of calls. The <TT>up</TT> and <TT>down</TT> commands select the
next or preceding activation record. Finally, the <TT>frame</TT> command
gives a description of the current record.<BR>
<BR>
<HR>
<A HREF="book-ora096.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora098.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
